package com.myidis.servlet;

import com.auxiliary.DICalculator;
import com.auxiliary.SeasonAdjuster;
import com.myidis.entity.*;
import com.myidis.mapper.CIDIIndexManagementMapper;
import com.myidis.mapper.DIResultMapper;
import com.myidis.mapper.QuotaDataMapper;
import com.myidis.request.DICalculatorReq;
import com.myidis.request.SearchReq;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.auxiliary.TimeSequence;

import java.util.ArrayList;

@Service
public class DICalculateServlet {
    @Autowired
    private QuotaDataMapper quotaDataMapper;
    @Autowired
    private CIDIIndexManagementMapper cidiIndexManagementMapper;
    @Autowired
    private DIResultMapper diResultMapper;

    public ArrayList<IndexResultList> all() {
        return diResultMapper.list();
    }

    public ArrayList<FullDIResult> getData(IndexResultList sea) {
        return diResultMapper.getData(sea);
    }

    public FullDIResult getInfo(int sea) {
        return diResultMapper.getInfo(sea);
    }

    public ArrayList<DIResult> calculate(DICalculatorReq sea) {

        //先行指标组合合成指数计算
        //从传回的json中拿到指标名称，查找对应的指标
        ArrayList<TimeSequence> LeadQuotaSet = new ArrayList<>();
        ArrayList<AnalysisIndex> LeadDataSet = cidiIndexManagementMapper.getByUniformity(sea.getCombination(), "先行");
        //通过查到的指标，以其名称取到具体数据并生成时间序列
        TimeSequence LeadTs = new TimeSequence();
        for (AnalysisIndex a: LeadDataSet){
            LeadTs.Rebuild(quotaDataMapper.getByQuota(a.getIndex(),sea.getStartTime(), sea.getEndTime()));
            SeasonAdjuster tc = new SeasonAdjuster(LeadTs,1,1);
            LeadTs.setValueList(tc.getTCList());
            LeadQuotaSet.add(LeadTs);
        }
        //计算对应先行指标组合的扩散指数，一致，滞后指标组合的扩散指数计算同理
        DIResult LeadQuotaDIResult = new DICalculator(LeadQuotaSet).Calculate();
        DIResult finalLeadResult = new DIResult(sea.getSubject(), LeadTs.getDateList(),LeadQuotaDIResult,sea.getSpringDay());


        //一致指标组合扩散指数计算
        ArrayList<TimeSequence> CoinQuotaSet = new ArrayList<>();
        ArrayList<AnalysisIndex> CoinDataSet = cidiIndexManagementMapper.getByUniformity(sea.getCombination(), "一致");
        TimeSequence CoinTs = new TimeSequence();
        for (AnalysisIndex a: CoinDataSet) {
            CoinTs.Rebuild(quotaDataMapper.getByQuota(2,sea.getStartTime(), sea.getEndTime()));
            SeasonAdjuster tc = new SeasonAdjuster(CoinTs,1,1);
            CoinTs.setValueList(tc.getTCList());
            CoinQuotaSet.add(CoinTs);
        }
        DIResult CoinQuotaDIResult = new DICalculator(CoinQuotaSet).Calculate();
        DIResult finalCoinResult = new DIResult(sea.getSubject(), CoinTs.getDateList(),CoinQuotaDIResult,sea.getSpringDay());

        //滞后指标组合扩散指数计算
        ArrayList<TimeSequence> LagQuotaSet = new ArrayList<>();
        ArrayList<AnalysisIndex> LagDataSet = cidiIndexManagementMapper.getByUniformity(sea.getCombination(), "滞后");
        TimeSequence LagTs = new TimeSequence();
        for (AnalysisIndex a: LagDataSet){
            LagTs.Rebuild(quotaDataMapper.getByQuota(a.getIndex(), sea.getStartTime(), sea.getEndTime()));
            SeasonAdjuster tc = new SeasonAdjuster(LagTs,1,1);
            LagTs.setValueList(tc.getTCList());
            LagQuotaSet.add(LagTs);
        }
        DIResult LagQuotaDIResult = new DICalculator(LagQuotaSet).Calculate();
        DIResult finalLagResult = new DIResult(sea.getSubject(), LagTs.getDateList(),LagQuotaDIResult,sea.getSpringDay());

        //基准指数计算
//        ArrayList<TimeSequence> benchmarkSet = new ArrayList<>();
//        benchmarkSet.add(new TimeSequence(quotaDataMapper.getByOne(sea.getBenchmark())));
        SeasonAdjuster tc = new SeasonAdjuster(new TimeSequence(quotaDataMapper.getByOne(sea.getBenchmark())),1,1);

        ArrayList<DIResult> results = new ArrayList<>();
        results.add(finalLeadResult);
        results.add(finalCoinResult);
        results.add(finalLagResult);
//        results.add(tc.getTCList());


        /*
        场景：计算结果存入数据库
        问题：一个计算结果集由三个子集构成，保存进数据库比较 麻烦
        方法一：把数据结果集里的数据，以时间为单位，装载到一个对象里，再由对象一次性构成一条数据库语句
                关键点：需要生成生成多个对象
        方法二：先有结果集的成员变量生成一份只有分析主题，组合名称，时间，其余字段都为空的数据，然后分
                三次遍历结果集里，先行·一致·滞后三个集合遍历过程中update数据库
                关键点：多次update数据库
         纠结点： 哪一个运行起来更快 或者有什么更好的解决办法
         */

        //把计算结果注入数据库
        for(int i = 0; i < finalLeadResult.getCount(); i++){
            String subject = finalLeadResult.getSubject();
            String time = finalLeadResult.getDates().get(i);
            double LeadDI = finalLeadResult.getdI().get(i);
            double LeadMovingDI = finalLeadResult.getMovingDI().get(i);
            double LeadCummDI = finalLeadResult.getCummunativeDI().get(i);
            double CoinDI = finalCoinResult.getdI().get(i);
            double CoinMovingDI = finalCoinResult.getMovingDI().get(i);
            double CoinCummDI = finalCoinResult.getCummunativeDI().get(i);
            double LagDI = finalLagResult.getdI().get(i);
            double LagMovingDI = finalLagResult.getMovingDI().get(i);
            double LagCummDI = finalLagResult.getCummunativeDI().get(i);
            double benchmarkDI = tc.getTCList().get(i);


            FullDIResult DataSql = new FullDIResult(subject,time,LeadDI,LeadMovingDI,LeadCummDI,
                CoinDI,CoinMovingDI,CoinCummDI,LagDI,LagMovingDI,LagCummDI,benchmarkDI);


            diResultMapper.insertDetail(DataSql);
        }
        String subject = finalLeadResult.getSubject();
        String  combination = sea.getCombination();
        String calculator = sea.getCalculator();
        String calTime = sea.getCalTime();
        String startTime = sea.getStartTime();
        String endTime = sea.getEndTime();
        String springDay = sea.getSpringDay();
        IndexResultList ListSql = new IndexResultList(0,subject,springDay,calTime,combination,calculator,startTime,endTime);
        diResultMapper.insertList(ListSql);

        return results;
    }

    public int delect(int del) {
        diResultMapper.deleteData(del);
        return diResultMapper.delete(del);
    }



}
